<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
    
  <meta name="description" content="书山有路勤为径，学海无涯苦作舟！" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
    android使用协程 |  z阅读
  </title>
  
  <link rel="shortcut icon" href="/zreader/favicon.ico" />
  
  
<link rel="stylesheet" href="/zreader/css/style.css">

  
<script src="/zreader/js/pace.min.js"></script>


  

  

<meta name="generator" content="Hexo 4.2.0"></head>

</html>

<body>
  <div id="app">
    <main class="content">
      <section class="outer">
  <article id="post-android使用协程" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  android使用协程
</h1>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/zreader/2020/11/01/android%E4%BD%BF%E7%94%A8%E5%8D%8F%E7%A8%8B/" class="article-date">
  <time datetime="2020-11-01T05:51:13.000Z" itemprop="datePublished">2020-11-01</time>
</a>
      
    </div>
    

    
    
    <div class="tocbot"></div>





    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <p>本文只说明协程怎么在android中使用，如果您对协程的概念，语法等不熟悉，请自行搜索学习。</p>
<h3 id="1-添加协程依赖"><a href="#1-添加协程依赖" class="headerlink" title="1.添加协程依赖"></a>1.添加协程依赖</h3><p>当前最新版本1.3.9</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">implementation <span class="string">'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'</span></span><br></pre></td></tr></table></figure>

<h3 id="2-实现BaseActivity"><a href="#2-实现BaseActivity" class="headerlink" title="2.实现BaseActivity"></a>2.实现BaseActivity</h3><p>为了开发方便这里BaseActivity里实现协程，其他Activity都继承BaseActivity。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseActivity</span> : <span class="type">AppCompatActivity</span></span>(), CoroutineScope <span class="keyword">by</span> MainScope()&#123;</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onDestroy</span><span class="params">()</span></span> &#123;</span><br><span class="line">        <span class="keyword">super</span>.onDestroy()</span><br><span class="line">        cancel()</span><br><span class="line">    &#125;   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如果您不想这样写个BaseActivity,当然也是可以的。一定 一定 一定 要记着在onDestory中取消协程，否则容易造成内存泄漏哦！</p>
<h3 id="3-使用协程"><a href="#3-使用协程" class="headerlink" title="3.使用协程"></a>3.使用协程</h3><p>在MainActivity中实现如图所示的功能。即下拉刷新并发发送网络请求，当所有请求都完成后刷新列表。</p>
<img src="https://s1.ax1x.com/2020/11/01/BwMVpT.png" alt="图片" style="zoom:50%;" align='left'/>


<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> : <span class="type">BaseActivity</span></span>() &#123;</span><br><span class="line">    <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="type">Bundle</span>?)</span></span> &#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line">        <span class="comment">//...省略其他代码</span></span><br><span class="line">        mRefreshView.setOnRefreshListener &#123;</span><br><span class="line">            refreshBookChapters()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">refreshBookChapters</span><span class="params">()</span></span> &#123;</span><br><span class="line">        launch(Dispatchers.Main) &#123;</span><br><span class="line">            <span class="keyword">val</span> temps = arrayListOf&lt;Deferred&lt;List&lt;Chapter&gt;&gt;&gt;()</span><br><span class="line">            <span class="keyword">for</span> (book <span class="keyword">in</span> bookShelfList) &#123;</span><br><span class="line">                <span class="keyword">val</span> temp = async &#123;</span><br><span class="line">                    Api.getChapters(book,<span class="literal">null</span>)</span><br><span class="line">                &#125;</span><br><span class="line">                temps.add(temp)</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (temp <span class="keyword">in</span> temps)&#123;</span><br><span class="line">                temp.await()</span><br><span class="line">            &#125;</span><br><span class="line">            adapter?.notifyDataSetChanged()</span><br><span class="line">            mRefreshView.isRefreshing = <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">       </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>launch(Dispatchers.Main) 即启用一个协程，Dispatchers.Main说明改协程运行在UI线程上，即在该协程里可以直接操作UI。</p>
<p>async即并发的在IO线程进行网络请求。接下来我们看一下 Api.getChapters(book,null)是什么样子的</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">suspend</span> <span class="function"><span class="keyword">fun</span> <span class="title">getChapters</span><span class="params">(book: <span class="type">Book</span>, isCache: ((<span class="type">url</span>: <span class="type">String</span>) -&gt; <span class="type">Boolean</span>)?)</span></span>: List&lt;Chapter&gt; = withContext(Dispatchers.IO) &#123;</span><br><span class="line">        <span class="keyword">val</span> result = arrayListOf&lt;Chapter&gt;()</span><br><span class="line">        <span class="keyword">val</span> id = getSourceId(book.bookCUrl)</span><br><span class="line">        <span class="keyword">if</span> (id != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">val</span> config = SourceManager.bookSourceConfigs[id]</span><br><span class="line">                <span class="keyword">val</span> url = <span class="keyword">if</span> (book.lastPageUrl.isNotEmpty()) book.lastPageUrl <span class="keyword">else</span> book.chapterUrl</span><br><span class="line">                <span class="keyword">val</span> dbListDeferred = async &#123; ChapterDao.getChapters(book.id ?: <span class="string">""</span>) &#125;</span><br><span class="line">                <span class="keyword">val</span> responseDeferred = async &#123;</span><br><span class="line">                   OkHttpClientManager.requestGet(url, config.charset)</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">val</span> dbList = dbListDeferred.await()</span><br><span class="line">                <span class="keyword">val</span> response= responseDeferred.await()</span><br><span class="line">                <span class="keyword">val</span> list = HTMLParsing.getChapters(book, response.body, config)</span><br><span class="line">                <span class="comment">//...省略相关业务代码</span></span><br><span class="line">            &#125; <span class="keyword">catch</span> (e: java.lang.Exception) &#123;&#125;</span><br><span class="line">        &#125;</span><br><span class="line">        result</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>suspend修饰符 告诉编译器getChapters函数需要在协程中执行。withContext(Dispatchers.IO)说明了该方法运行与io线程。</p>
<p>到此这个简单的业务就完成了。</p>
<h4 id="以上代码是小说阅读器-Z阅读的部分代码！"><a href="#以上代码是小说阅读器-Z阅读的部分代码！" class="headerlink" title="以上代码是小说阅读器 Z阅读的部分代码！"></a>以上代码是小说阅读器 <a href="https://zhufred.gitee.io/zreader/">Z阅读</a>的部分代码！</h4>
      
      <!-- 打赏 -->
      
        <div id="reward-btn">
          打赏
        </div>
        
    </div>
    <footer class="article-footer">
      <a data-url="https://yukun314.gitee.io/zreader/2020/11/01/android%E4%BD%BF%E7%94%A8%E5%8D%8F%E7%A8%8B/" data-id="ckpux5kir0002f0cp1266cwfg"
        class="article-share-link">分享</a>
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/zreader/tags/android-kotlin-%E5%8D%8F%E7%A8%8B/" rel="tag">android  kotlin 协程</a></li></ul>

    </footer>

  </div>

  
  
  <nav class="article-nav">
    
    
      <a href="/zreader/2020/10/04/TabLayout-%E6%96%87%E5%AD%97-%E5%9B%BE%E6%A0%87-%E8%83%8C%E6%99%AF%E5%8A%A8%E7%94%BB/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">TabLayout  文字/图标/背景动画</div>
      </a>
    
  </nav>


  

  
  
<!-- valine评论 -->
<div id="vcomments-box">
    <div id="vcomments">
    </div>
</div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src='https://cdn.jsdelivr.net/npm/valine@1.3.10/dist/Valine.min.js'></script>
<script>
    new Valine({
        el: '#vcomments',
        notify: false,
        verify: false,
        app_id: 'nncc5vxkXViaodaRNq6mdmPB-gzGzoHsz',
        app_key: 'BT53GVtaskTdp1jDv0zVWW3u',
        path: window.location.pathname,
        avatar: 'mp',
        placeholder: '留下您宝贵的意见！',
        recordIP: true
    });
    const infoEle = document.querySelector('#vcomments .info');
    if (infoEle && infoEle.childNodes && infoEle.childNodes.length > 0) {
        infoEle.childNodes.forEach(function (item) {
            item.parentNode.removeChild(item);
        });
    }
</script>
<style>
    #vcomments-box {
        padding: 5px 30px;
    }

    @media screen and (max-width: 800px) {
        #vcomments-box {
            padding: 5px 0px;
        }
    }

    #vcomments-box #vcomments {
        background-color: #fff;
    }

    .v .vlist .vcard .vh {
        padding-right: 20px;
    }

    .v .vlist .vcard {
        padding-left: 10px;
    }
</style>

  

  
  
  

</article>
</section>
      <footer class="footer">
  <div class="outer">
    <ul class="list-inline">
      <li style="text-align:center;font-size:1.5em">
        &copy;
        2019-2021
        &nbsp;&nbsp;&nbsp;fred
      </li>
    </ul>
	<p>App使用的所有小说为转载作品，所有章节均由网友上传，App只是为了宣传本书让更多读者欣赏。</p>
  </div>
</footer>
    <div class="to_top">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>
      </div>
    </main>
    
    <aside class="sidebar">
      
        <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/zreader/"><img src="/zreader/images/icon.png" alt="z阅读"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/zreader/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/zreader/archives">目录</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      
      <a class="nav-item-link" target="_blank" href="/zreader/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
      </aside>
      <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>赐予我力量吧</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="/zreader/images/zhifubao.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="/zreader/images/weixin.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
      
<script src="/zreader/js/jquery-2.0.3.min.js"></script>


<script src="/zreader/js/jquery.justifiedGallery.min.js"></script>


<script src="/zreader/js/lazyload.min.js"></script>


<script src="/zreader/js/busuanzi-2.3.pure.min.js"></script>




  
<script src="/zreader/js/tocbot.min.js"></script>

  <script>
    // Tocbot_v4.7.0  http://tscanlin.github.io/tocbot/
    tocbot.init({
      tocSelector: '.tocbot',
      contentSelector: '.article-entry',
      headingSelector: 'h1, h2, h3, h4, h5, h6',
      hasInnerContainers: true,
      scrollSmooth: true,
      positionFixedSelector: '.tocbot',
      positionFixedClass: 'is-position-fixed',
      fixedSidebarOffset: 'auto',
    });
  </script>


<script>
  var ayerConfig = {
    mathjax: false
  }
</script>


<script src="/zreader/js/ayer.js"></script>


<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">



<script type="text/javascript" src="https://js.users.51.la/20544303.js"></script>
  
  
  </div>
</body>

</html>